﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace PJ.Data
{
    /// <summary>
    /// ObjectProviderClient : ClientBase object for WCF services.
    /// </summary>
    /// <typeparam name="S"></typeparam>
    /// <typeparam name="D">Must be a concrete object. Interfaces and Abstract objects are not supported by WCF</typeparam>
    public abstract class ObjectProviderClient<S, D> : ClientBase<S>, IObjectProvider<D>, IDisposable
        where D : BaseObjectData, new()
        where S : class, IObjectProvider<D>
    {

        protected ObjectProviderClient()
            : base(typeof(S).Name)
        {
        }

        protected ObjectProviderClient(string endpointConfigurationName) :
            base(endpointConfigurationName)
        {
        }

        protected ObjectProviderClient(string endpointConfigurationName, string remoteAddress) :
            base(endpointConfigurationName, remoteAddress)
        {
        }

        protected ObjectProviderClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
            base(endpointConfigurationName, remoteAddress)
        {
        }

        protected ObjectProviderClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
            base(binding, remoteAddress)
        {
        }


        public D GetData(string globalId)
        {
            if (globalId == null)
                throw new ArgumentNullException();
            return base.Channel.GetData(globalId);
        }

        public D Find(string globalId)
        {
            if (globalId == null)
                throw new ArgumentNullException();
            return base.Channel.Find(globalId);
        }

        public D CachedGet(string globalId)
        {
            if (globalId == null)
                throw new ArgumentNullException();
            return base.Channel.CachedGet(globalId);
        }

        public D CachedFind(string globalId)
        {
            if (globalId == null)
                throw new ArgumentNullException();
            return base.Channel.CachedFind(globalId);
        }

        public bool Exist(string globalId)
        {
            if (globalId == null)
                throw new ArgumentNullException();
            return base.Channel.Exist(globalId);
        }

        public void Delete(D dataObject)
        {
            if (dataObject == null)
                throw new ArgumentNullException();
            Delete(dataObject.GlobalId);
        }
        public void Delete(string globalId)
        {
            if (globalId == null)
                throw new ArgumentNullException();
            base.Channel.Delete(globalId);
        }

        public void Persist(D data)
        {
            if (data == null)
                throw new ArgumentNullException();
            base.Channel.Persist(data);
        }
        public D PersistAndGet(D data)
        {
            if (data == null)
                throw new ArgumentNullException();
            return base.Channel.PersistAndGet(data);
        }
        public void Dispose()
        {
            if (State == CommunicationState.Faulted)
                Abort();
            else
                Close();
        }

        public D CreateNewItem()
        {
            return new D();
        }



        #region Interface override

        IObjectData IObjectProvider.GetData(string globalId)
        {
            return GetData(globalId);
        }

        IObjectData IObjectProvider.CachedGet(string globalId)
        {
            return CachedGet(globalId);
        }

        IObjectData IObjectProvider.Find(string globalId)
        {
            return Find(globalId);
        }

        IObjectData IObjectProvider.CachedFind(string globalId)
        {
            return CachedFind(globalId);
        }

        IObjectData IObjectProvider.PersistAndGet(IObjectData data)
        {
            return PersistAndGet((D)data);
        }

        void IObjectProvider.Persist(IObjectData data)
        {
            Persist((D)data);
        }

        IObjectData IObjectProvider.CreateNewItem()
        {
            return CreateNewItem();
        }

        #endregion     

    }
}
